﻿//
// *************************************************************************************
// WP-Framework
// 
// Developed by
// Lukas Kretschmar (lkretschmar.dev@bluewin.ch)
//
// Switzerland, Copyright (c) 2013 lkretschmar
// This content is released under the MIT License (http://opensource.org/licenses/MIT).
//     
// *************************************************************************************
//
//



using Microsoft.VisualStudio.TestTools.UnitTesting;
using KretschIT.WP_Fx.EasyMoq.Test.Helpers.Objects;
using KretschIT.WP_Fx.Testing;

namespace KretschIT.WP_Fx.EasyMoq.Test.IntegrationTests
{
    [TestClass]
    public class GenericFuncTest
    {
        private IMock<ITestGenericMethod> mock;

        [TestInitialize]
        public void Init()
        {
            this.mock = Easy.Moq.Mock<ITestGenericMethod>();
        }

        [TestMethod]
        public void Test_Setup_Verify()
        {
            this.mock.Setup(m => m.Func<int>());

            this.mock.Verify(m => m.Func<int>(), Condition.Never());
        }

        [TestMethod]
        public void Test_Setup_Execute_Verify()
        {
            this.mock.Setup(m => m.Func<int>(42)).Returns(1337);

            var result = this.mock.Object.Func<int>(42);

            Assert.AreEqual(1337, result);
            this.mock.Verify(m => m.Func<int>(42), Condition.Once());
            this.mock.Verify(m => m.Func<string>("42"), Condition.Never());
        }

        [TestMethod]
        public void Test_Setup_ExecuteException_Verify()
        {
            this.mock.Setup(m => m.Func<int>()).Throws(new TestException());

            var result = this.mock.Object.Func<int>(42);
            ExceptionAssert.Throws<TestException>(() =>
                {
                    this.mock.Object.Func<int>();
                });

            Assert.AreEqual(0, result);
            this.mock.Verify(m => m.Func<int>(42), Condition.Once());
            this.mock.Verify(m => m.Func<int>(), Condition.Once());
        }

        [TestMethod]
        public void Test_Setup_ExecuteDiffrentFunc_Verify()
        {
            this.mock.Setup(m => m.Func<string>()).Returns("Hello");
            this.mock.Setup(m => m.Func<string>("world")).Returns(" World");

            var obj = this.mock.Object;
            var message = obj.Func<string>();
            message += obj.Func<string>("world");

            Assert.AreEqual("Hello World", message);
            this.mock.Verify(m => m.Func<string>(), Condition.Once());
            this.mock.Verify(m => m.Func<string>("world"), Condition.Once());
        }

        [TestMethod]
        public void Test_Setup_ExecuteX_Verify()
        {
            this.mock.Setup(m => m.Func<int>()).Returns(10);

            var obj = this.mock.Object;
            var result = obj.Func<int>();
            result += obj.Func<int>();
            result += obj.Func<int>();

            Assert.AreEqual(30, result);
            this.mock.Verify(m => m.Func<int>(), Condition.Exactly(3));
        }

        [TestMethod]
        public void Test_Setup_Execute_Verify_WrongMethod()
        {
            this.mock.Setup(m => m.Func<string>("hello")).Returns("true");
            this.mock.Setup(m => m.Func("hello")).Returns("false");

            var value = this.mock.Object.Func<string>("hello");

            Assert.AreEqual("true", value);
            this.mock.Verify(m => m.Func<string>("hello"), Condition.Once());
            this.mock.Verify(m => m.Func("hello"), Condition.Never());
        }
    }
}
